﻿using QuadRemote.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace QuadRemote
{
    public partial class ConfigField : Control
    {
        private Label nameLabel;

        private VarValue value;

        private ConfigNumericTextField[] textbox;
        private CheckBox[] bitmaskCheckbox;
        private ComboBox dropdown;

        public class ComboEnumItem
        {
            public int key;
            public String value;

            public ComboEnumItem(int k, String val)
            {
                key = k;
                value = val;
            }

            public override String ToString()
            {
                return value;
            }
        }
        public ConfigField(VarValue var)
        {
            value = var;
            InitializeComponent();

            int baseWidth = 55;
            int margin = 3;

            String name = value.name;
            String valtype = "";
            if (name.IndexOf('(') > 0)
            {
                valtype = name.Substring(name.IndexOf('(') + 1, name.Length - name.IndexOf('(') - 2).Trim();
                name = name.Substring(0, name.IndexOf('(')).Trim();
            }

            nameLabel = new Label();
            nameLabel.Text = name;
            nameLabel.Location = new Point(0, -3);
            nameLabel.Font = Tools.getPrimaryFont();
            nameLabel.Size = new Size(210, 20);
            nameLabel.TextAlign = ContentAlignment.MiddleRight;
            this.Controls.Add(nameLabel);

            Label typeLabel = new Label();
            typeLabel.Text = valtype;
            typeLabel.Location = new Point(0, 13);
            typeLabel.TextAlign = ContentAlignment.MiddleRight;
            typeLabel.Font = new Font(Tools.getPrimaryFont().FontFamily, 7);
            typeLabel.Size = new Size(210, 13);
            this.Controls.Add(typeLabel);

            this.Size = new Size(500, 25);

            if (var.isEnum)
            {
                dropdown = new ComboBox();
                dropdown.DropDownStyle = ComboBoxStyle.DropDownList;
                
                foreach (int k in var.enumValues.Keys)
                {
                    //Console.WriteLine(" -> " + k + " = " + var.enumValues[k] + " -- " + (int)var.value[0]);
                    dropdown.Items.Add(new ComboEnumItem(k, var.enumValues[k]));
                    if (k == var.value[0]) dropdown.SelectedIndex = dropdown.Items.Count - 1;
                }
                dropdown.Size = new Size((baseWidth +margin) * 3, 23);
                dropdown.Location = new Point(220, 0);
                Controls.Add(dropdown);
                dropdown.SelectedIndexChanged += dropdown_SelectedIndexChanged;
            }
            else if (var.valueType == 2) // bitmask
            {
                int i;
                bitmaskCheckbox = new CheckBox[var.intBits];
                Console.WriteLine((int)var.value[0]);

                for (i=0;i< var.intBits;i++)
                {
                    bitmaskCheckbox[i] = new CheckBox();
                    bitmaskCheckbox[i].Location = new Point(220 + i * 26, 0);
                    bitmaskCheckbox[i].Checked = (var.value[0] & (1 << i)) != 0;
                    bitmaskCheckbox[i].CheckedChanged += ConfigField_CheckChanged;
                    bitmaskCheckbox[i].Size = new Size(25, 25);
                    Controls.Add(bitmaskCheckbox[i]);
                }
            }
            else
            {
                textbox = new ConfigNumericTextField[var.numValues];
                int i;

                byte[] subVar = new byte[var.bytesPerValue];

                int rows = var.numValues > 4 ? 2 : 1;
                int perRow = var.numValues / rows;

                int r = 0;
                int p = 0;

                for (i = 0; i < var.numValues; i++)
                {
                    textbox[i] = new ConfigNumericTextField(var.valueType == 1, var.intBits, var.floatBits);
                    textbox[i].Size = new Size(baseWidth, 23);
                    textbox[i].Location = new Point(220 + p * (baseWidth + margin), 24 * r);
                    Array.Copy(var.value, i * var.bytesPerValue, subVar, 0, var.bytesPerValue);
                    textbox[i].setValue(subVar);
                    textbox[i].LostFocus += ConfigField_TextChanged;
                    Controls.Add(textbox[i]);
                    p++;
                    if (p == perRow)
                    {
                        p = 0;
                        r++;
                    }
                }

                this.Size = new Size(500, 25*rows);
            }

        }

        void ConfigField_CheckChanged(object sender, EventArgs e)
        {
            byte mask = 0;
            int c = 0;

            foreach (CheckBox cb in bitmaskCheckbox)
            {
                mask |= (byte)(cb.Checked ? (1 << c) : 0);
                c++;
            }

            byte[] packet = new byte[value.groupName.Length + 1 + value.name.Length + 1 + 1];

            int pos = 0;
            pos = Tools.stringToBytes(value.groupName, ref packet, pos);
            pos = Tools.stringToBytes(value.name, ref packet, pos);

            packet[pos] = mask;

            new CommandOut(CommandId.CMD_CONFIG_VALUE, packet).send();
        }

        void ConfigField_TextChanged(object sender, EventArgs e)
        {
            int index = Array.IndexOf(textbox, sender);

            Array.Copy(textbox[index].value, 0, value.value, index * value.bytesPerValue, value.bytesPerValue);

            byte[] packet = new byte[value.groupName.Length + 1 + value.name.Length + 1 + value.totalBytes];

            //packet[0] = (byte)Bluetooth.CMD_ID.CMD_CONFIG_VALUE;
            int pos = 0;
            pos = Tools.stringToBytes(value.groupName, ref packet, pos);
            pos = Tools.stringToBytes(value.name, ref packet, pos);
            Array.Copy(value.value, 0, packet, pos, value.totalBytes);

            Console.WriteLine(Tools.getHexString(packet));
            //BluetoothPacket btPacket = new BluetoothPacket(true, packet);

            new CommandOut(CommandId.CMD_CONFIG_VALUE, packet).send();

            //Core.Bluetooth.instance().sendPriorityPacket(packet);
        }

        void dropdown_SelectedIndexChanged(object sender, EventArgs e)
        {
            value.value[0] = (byte)dropdown.SelectedIndex;

            byte[] packet = new byte[value.groupName.Length + 1 + value.name.Length + 1 + value.totalBytes];

            //packet[0] = (byte)Bluetooth.CMD_ID.CMD_CONFIG_VALUE;
            int pos = 0;
            pos = Tools.stringToBytes(value.groupName, ref packet, pos);
            pos = Tools.stringToBytes(value.name, ref packet, pos);
            Array.Copy(value.value, 0, packet, pos, value.totalBytes);

            //BluetoothPacket btPacket = new BluetoothPacket(true, packet);
            //Core.Bluetooth.instance().sendPriorityPacket(packet);

            new CommandOut(CommandId.CMD_CONFIG_VALUE, packet).send();
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);
        }
    }
}
